/**
 * Image.m by Giraldo Rosales.
 * Visit www.liquidgear.net for documentation and updates.
 *
 * Copyright (c) 2009 Nitrogen Design, Inc. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 **/
#if LG_USE_IMAGE

#import <zlib.h>
#import "CJSONDeserializer.h"
#import "Image.h"
#import "LiquidGearAppDelegate.h"
#import "Utils.h"
#import "WebController.h"

@implementation Image

@synthesize imageView, quality, receivedData, uploadURL, uploadType, photoFilename, viewController;

- (id)initWithController:(WebController*)controller {
	viewController	= controller;
	return self;
}

- (void) getImage:(NSString*)type edit:(NSString*)edit name:(NSString*)name url:(NSString*)url quality:(NSString*)compressQuality {	
	self.uploadURL			= url;
	self.uploadType			= type;
	self.photoFilename	= name;
	self.quality				= compressQuality;
	
	UIImagePickerController *picker = [[UIImagePickerController alloc] init];
	picker.delegate = self;
	
	BOOL openPicker	= TRUE;
	
	if([edit isEqualToString:@"yes"]) {
		picker.allowsImageEditing = YES;
	} else {
		picker.allowsImageEditing = NO;
	}
	
	if([type isEqualToString:@"camera"] && [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
		picker.sourceType = UIImagePickerControllerSourceTypeCamera;
	} 
	else if([type isEqualToString:@"library"]) {
		picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
	} else {
		//Create image from url path
		[self grabImage:photoFilename];
		openPicker	= FALSE;
	}
	
	
	if(openPicker) {
		//Open image picker view
		LiquidGearAppDelegate *LGdelegate = (LiquidGearAppDelegate*)[[UIApplication sharedApplication] delegate];
		CGRect winRect		= [[UIScreen mainScreen] applicationFrame];
		winRect.origin.y	= 0;
		picker.view.frame	= winRect;
		[LGdelegate.window addSubview:picker.view];
	}
}

- (void)grabImage:(NSString *)path {
	NSLog(@"path: %@", path);
	
	NSURLRequest *req			= [NSURLRequest requestWithURL:[NSURL URLWithString:path] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
	NSURLConnection *conn	= [[NSURLConnection alloc] initWithRequest:req delegate:self];
	NSMutableData *data		= nil;
	
	if (conn) {
		receivedData	=	[[NSMutableData data] retain];
	} else {
    // inform the user that the download could not be made
	}
}

#ifdef __IPHONE_3_0
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
	UIImage *image;
	
	if(picker.allowsImageEditing) {
		image = [info objectForKey:UIImagePickerControllerEditedImage];
	} else {
		image = [info objectForKey:UIImagePickerControllerOriginalImage];
	}

	
	if([uploadURL isEqualToString:@"local"]) {
		[self saveImage:image];
	}
	else if([uploadURL isEqualToString:@"album"]) {
		[self saveImageToAlbum:image];
	} else {
		[self uploadImage:image];
	}
	
	//Get rid of picker
	[picker.view removeFromSuperview];
	[picker release];
}
#else
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
	if([uploadURL isEqualToString:@"local"]) {
		[self saveImage:image];
	}
	else if([uploadURL isEqualToString:@"album"]) {
		[self saveImageToAlbum:image];
	} else {
		[self uploadImage:image];
	}
	
	//Get rid of picker
	[picker.view removeFromSuperview];
	[picker release];
}
#endif

- (void)saveImage:(UIImage*)image {
	NSLog(@"Image::saveImage");
	NSData *imageData		= UIImageJPEGRepresentation(image, [quality floatValue]);
	NSString *filePath	= nil;
	
	filePath			= [NSString stringWithFormat:@"%@/%@", NSTemporaryDirectory(), photoFilename];
	int fileSize	= [imageData length]/1024;
	bool saved		= [imageData writeToFile:filePath atomically:YES];
	
	NSString *jsOut;
	NSDictionary *callback;
	NSDictionary *imgObj;
	
	// now lets make the connection to the web
	if(saved) {
		imgObj		= [NSDictionary dictionaryWithObjectsAndKeys:
								 filePath, @"url",
								 photoFilename, @"name",
								 @"image/jpeg", @"type",
								 [NSString stringWithFormat:@"%f", fileSize], @"size",
								 nil
								 ];
		
		callback	= [NSDictionary dictionaryWithObjectsAndKeys:
								 imgObj, @"file",
								 uploadType, @"type",
								 nil
								 ];
	} else {
		imgObj		= [NSDictionary dictionaryWithObjectsAndKeys:
								 @"Image could not be saved.", @"desc",
								 nil
								 ];
		
		callback	= [NSDictionary dictionaryWithObjectsAndKeys:
								 imgObj, @"error",
								 uploadType, @"type",
								 nil
								 ];
	}
	
	NSLog(@"Image::filePath: %@", filePath);
	[[[Utils alloc] autorelease] jsCall:viewController.webView type:@"image" data:callback directCall:nil];
}

- (void)saveImageToAlbum:(UIImage*)image {
	NSLog(@"Image::saveImage");
	NSData *imageData		= UIImageJPEGRepresentation(image, [quality floatValue]);
	NSString *filePath	= [NSString stringWithFormat:@"%@/%@", NSTemporaryDirectory(), photoFilename];
	int fileSize				= [imageData length]/1024;
	NSString *jsOut;
	
	NSDictionary *callback;
	NSDictionary *imgObj;
	
	// now lets make the connection to the web
	imgObj		= [NSDictionary dictionaryWithObjectsAndKeys:
								 filePath, @"url",
								 photoFilename, @"name",
								 @"image/jpeg", @"type",
								 [NSString stringWithFormat:@"%f", fileSize], @"size",
								 nil
								 ];
		
	callback	= [NSDictionary dictionaryWithObjectsAndKeys:
								 imgObj, @"file",
								 uploadType, @"type",
								 nil
								 ];
	
	
	NSLog(@"Image::filePath: %@", filePath);
	UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil); 	
	[[[Utils alloc] autorelease] jsCall:viewController.webView type:@"image" data:callback directCall:nil];
}

- (void)uploadImage:(UIImage*)image {
	NSData *imageData = UIImageJPEGRepresentation(image, [quality floatValue]);
	
	// setting up the request object now
	NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
	[request setURL:[NSURL URLWithString:uploadURL]];
	[request setHTTPMethod:@"POST"];
	
	NSString *boundary		= [NSString stringWithString:@"0xKhTmLbOuNdArY"];
	NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
	[request addValue:contentType forHTTPHeaderField: @"Content-Type"];
	
	NSMutableData *body = [NSMutableData data];
	[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[[NSString stringWithString:@"Content-Disposition: form-data; name=\"type\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[[NSString stringWithFormat:@"\r\n%@", uploadType] dataUsingEncoding:NSUTF8StringEncoding]];
	
	[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"\r\n", photoFilename] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
	[body appendData:[NSData dataWithData:imageData]];
	[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
	[request setHTTPBody:body];
	
	// now lets make the connection to the web
	NSData *returnData	= [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
	NSString *jsonString	= [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
	NSData *jsonData			= [jsonString dataUsingEncoding:NSUTF8StringEncoding];
	
	NSDictionary *jsonObj	= [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:nil];
	[[[Utils alloc] autorelease] jsCall:viewController.webView type:@"image" data:jsonObj directCall:nil];
	
	NSLog(uploadType);
	NSLog(@"finishedUploading");
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
	[picker.view removeFromSuperview];
	[picker release];
	
	NSString *jsCallback = @"lg.nextCall();";
	[viewController.webView stringByEvaluatingJavaScriptFromString:jsCallback];
}
/*
//Uses zlib to compress the given data.
- (NSData *)zcompress: (NSData *)data {
	if (!data || [data length] == 0) {
		return nil;
	}
	
	// zlib compress doc says destSize must be 1% + 12 bytes greater than source.
	uLong destSize = [data length] * 1.001 + 12;
	NSMutableData *destData = [NSMutableData dataWithLength:destSize];
	
	int error = zcompress([destData mutableBytes], &destSize, [data bytes], [data length]);
	if (error != Z_OK) {
		NSLog(@"%s: self:0x%p, zlib error on compress:%d\n",__func__, self, error);
		return nil;
	}
	
	[destData setLength:destSize];
	return destData;
}
*/
/*
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
	NSLog(@"photo: upload finished!");
	
	NSString *aStr = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
	
	//upload.php should return "filename=<filename>"
	NSLog(aStr);
	NSArray * parts = [aStr componentsSeparatedByString:@"="];
	//set filename
	lastUploadedPhoto = (NSString *)[parts objectAtIndex:1];
	
	//now the callback: return lastUploadedPhoto
	
	NSString * jsCallBack = nil;
	
	if(lastUploadedPhoto == nil) lastUploadedPhoto = @"ERROR";
	
	jsCallback = [[[Utils alloc] autorelease] jsCall:@"image" data:lastUploadedPhoto];
	
	[viewController.webView stringByEvaluatingJavaScriptFromString:jsCallBack];
	
	NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
	NSLog(jsCallBack);
	
	// release the connection, and the data object
	[connection release];
	[receivedData release];
}
*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
	// do something with the data
	if([uploadType isEqualToString:@"web"]) {
		UIImage *image		= [UIImage imageWithData:receivedData];
		
		if([uploadURL isEqualToString:@"local"]) {
			[self saveImage:image];
		}
		else if([uploadURL isEqualToString:@"album"]) {
			[self saveImageToAlbum:image];
		} else {
			[self uploadImage:image];
		}	
	}
	// receivedData is declared as a method instance elsewhere
	NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
	
	// release the connection, and the data object
	[connection release];
	[receivedData release];
	//[self uploadSucceeded:uploadDidSucceed];
}

/*
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response {
	//added by urbian.org
	NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
	NSLog(@"HTTP Status Code: %i", [httpResponse statusCode]);
	
	[receivedData setLength:0];
}
*/

- (void) connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response {
	[receivedData setLength:0];
}

- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data {
	//NSLog(@"%s: self:0x%p\n", __func__, self);
	
	//NSString *reply = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
	//NSLog(@"%s: data: %s\n", __func__, [reply UTF8String]);
	
	//if ([reply hasPrefix:@"YES"]) {
	//	uploadDidSucceed = YES;
	//}
	
	[receivedData appendData:data];
}

/*
 * Failed with Error
 */
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
	[connection release];
	
	// receivedData is declared as a method instance elsewhere
	[receivedData release];
	
	// inform the user
	NSLog(@"Connection failed! Error - %@ %@", [error localizedDescription], [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
	//[self uploadSucceeded:NO];
}

@end
#endif